#include "common/pch.h"

#include <cftc/reflect/class.h>
#include <cftc/reflect/field.h>

#include <format>

#include "dbc/structure.h"

#include <cftf/loger/syslog.h>

namespace dbc
{

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(AreaTableEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(AreaTriggerEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(AuctionHouseEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(BankBagSlotPricesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CharStartOutfitEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ChatChannelsEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(ChrClassesEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.ChrClassesEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(ClassID);
		CFT_IMPLEMENT_REFLECT_FIELD(powerType);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(name, R"(wow_dbc:"element_size:8")");
		CFT_IMPLEMENT_REFLECT_FIELD(spellfamily);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(ChrRacesEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.ChrRacesEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(RaceID);
		CFT_IMPLEMENT_REFLECT_FIELD(FactionID);
		CFT_IMPLEMENT_REFLECT_FIELD(model_m);
		CFT_IMPLEMENT_REFLECT_FIELD(model_f);
		CFT_IMPLEMENT_REFLECT_FIELD(TeamID);
		CFT_IMPLEMENT_REFLECT_FIELD(startingTaxiMask);
		CFT_IMPLEMENT_REFLECT_FIELD(CinematicSequence);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(name, R"(wow_dbc:"element_size:8")");
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CinematicSequencesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(CreatureDisplayInfoEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.CreatureDisplayInfofmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(Displayid);
		CFT_IMPLEMENT_REFLECT_FIELD(ExtendedDisplayInfoID);
		CFT_IMPLEMENT_REFLECT_FIELD(scale);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CreatureDisplayInfoExtraEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CreatureFamilyEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CreatureSpellDataEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(CreatureTypeEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(DurabilityCostsEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(DurabilityQualityEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(EmotesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(EmotesTextEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(FactionEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(FactionTemplateEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(GameObjectDisplayInfoEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ItemBagFamilyEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ItemClassEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ItemRandomPropertiesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ItemSetEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(LiquidTypeEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(LockEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(MailTemplateEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(MapEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.MapEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(MapID);
		CFT_IMPLEMENT_REFLECT_FIELD(map_type);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(name, R"(wow_dbc:"element_size:dbc.MapEntry.NAME_SIZE")");
		CFT_IMPLEMENT_REFLECT_FIELD(linked_zone);
		CFT_IMPLEMENT_REFLECT_FIELD(multimap_id);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(MovieEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(QuestSortEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SkillRaceClassInfoEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(SkillLineEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.SkillLinefmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(id);
		CFT_IMPLEMENT_REFLECT_FIELD(categoryId);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(name, R"(wow_dbc:"element_size:8")");
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SkillLineAbilityEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SoundEntriesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(ClassFamilyMask, cftc::reflect::Object);
		CFT_IMPLEMENT_REFLECT_FIELD(Flags);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(SpellEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.SpellEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(Id);
		CFT_IMPLEMENT_REFLECT_FIELD(School);
		CFT_IMPLEMENT_REFLECT_FIELD(Category);
		CFT_IMPLEMENT_REFLECT_FIELD(Dispel);
		CFT_IMPLEMENT_REFLECT_FIELD(Mechanic);
		CFT_IMPLEMENT_REFLECT_FIELD(Attributes);
		CFT_IMPLEMENT_REFLECT_FIELD(AttributesEx);
		CFT_IMPLEMENT_REFLECT_FIELD(AttributesEx2);
		CFT_IMPLEMENT_REFLECT_FIELD(AttributesEx3);
		CFT_IMPLEMENT_REFLECT_FIELD(AttributesEx4);
		CFT_IMPLEMENT_REFLECT_FIELD(Stances);
		CFT_IMPLEMENT_REFLECT_FIELD(StancesNot);
		CFT_IMPLEMENT_REFLECT_FIELD(Targets);
		CFT_IMPLEMENT_REFLECT_FIELD(TargetCreatureType);
		CFT_IMPLEMENT_REFLECT_FIELD(RequiresSpellFocus);
		CFT_IMPLEMENT_REFLECT_FIELD(CasterAuraState);
		CFT_IMPLEMENT_REFLECT_FIELD(TargetAuraState);
		CFT_IMPLEMENT_REFLECT_FIELD(CastingTimeIndex);
		CFT_IMPLEMENT_REFLECT_FIELD(RecoveryTime);
		CFT_IMPLEMENT_REFLECT_FIELD(CategoryRecoveryTime);
		CFT_IMPLEMENT_REFLECT_FIELD(InterruptFlags);
		CFT_IMPLEMENT_REFLECT_FIELD(AuraInterruptFlags);
		CFT_IMPLEMENT_REFLECT_FIELD(ChannelInterruptFlags);
		CFT_IMPLEMENT_REFLECT_FIELD(procFlags);
		CFT_IMPLEMENT_REFLECT_FIELD(procChance);
		CFT_IMPLEMENT_REFLECT_FIELD(procCharges);
		CFT_IMPLEMENT_REFLECT_FIELD(maxLevel);
		CFT_IMPLEMENT_REFLECT_FIELD(baseLevel);
		CFT_IMPLEMENT_REFLECT_FIELD(spellLevel);
		CFT_IMPLEMENT_REFLECT_FIELD(DurationIndex);
		CFT_IMPLEMENT_REFLECT_FIELD(powerType);
		CFT_IMPLEMENT_REFLECT_FIELD(manaCost);
		CFT_IMPLEMENT_REFLECT_FIELD(manaCostPerlevel);
		CFT_IMPLEMENT_REFLECT_FIELD(manaPerSecond);
		CFT_IMPLEMENT_REFLECT_FIELD(manaPerSecondPerLevel);
		CFT_IMPLEMENT_REFLECT_FIELD(rangeIndex);
		CFT_IMPLEMENT_REFLECT_FIELD(speed);
		CFT_IMPLEMENT_REFLECT_FIELD(modalNextSpell);
		CFT_IMPLEMENT_REFLECT_FIELD(StackAmount);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(Totem, R"(wow_dbc:"element_size:MAX_SPELL_TOTEMS")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(Reagent, R"(wow_dbc:"element_size:MAX_SPELL_REAGENTS")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(ReagentCount, R"(wow_dbc:"element_size:MAX_SPELL_REAGENTS")");
		CFT_IMPLEMENT_REFLECT_FIELD(EquippedItemClass);
		CFT_IMPLEMENT_REFLECT_FIELD(EquippedItemSubClassMask);
		CFT_IMPLEMENT_REFLECT_FIELD(EquippedItemInventoryTypeMask);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(Effect, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectDieSides, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectBaseDice, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectDicePerLevel, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectRealPointsPerLevel, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectBasePoints, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectMechanic, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectImplicitTargetA, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectImplicitTargetB, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectRadiusIndex, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectApplyAuraName, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectAmplitude, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectMultipleValue, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectChainTarget, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectItemType, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectMiscValue, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectTriggerSpell, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(EffectPointsPerComboPoint, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
		CFT_IMPLEMENT_REFLECT_FIELD(SpellVisual);
		CFT_IMPLEMENT_REFLECT_FIELD(SpellIconID);
		CFT_IMPLEMENT_REFLECT_FIELD(activeIconID);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(SpellName, R"(wow_dbc:"element_size:8")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(Rank, R"(wow_dbc:"element_size:8")");
		CFT_IMPLEMENT_REFLECT_FIELD(ManaCostPercentage);
		CFT_IMPLEMENT_REFLECT_FIELD(StartRecoveryCategory);
		CFT_IMPLEMENT_REFLECT_FIELD(StartRecoveryTime);
		CFT_IMPLEMENT_REFLECT_FIELD(MaxTargetLevel);
		CFT_IMPLEMENT_REFLECT_FIELD(SpellFamilyName);
		CFT_IMPLEMENT_REFLECT_FIELD(SpellFamilyFlags);
		CFT_IMPLEMENT_REFLECT_FIELD(MaxAffectedTargets);
		CFT_IMPLEMENT_REFLECT_FIELD(DmgClass);
		CFT_IMPLEMENT_REFLECT_FIELD(PreventionType);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(DmgMultiplier, R"(wow_dbc:"element_size:MAX_EFFECT_INDEX")");
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SpellRadiusEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SpellRangeEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(SpellShapeshiftFormEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.SpellShapeshiftfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(ID);
		CFT_IMPLEMENT_REFLECT_FIELD(flags1);
		CFT_IMPLEMENT_REFLECT_FIELD(creatureType);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SpellDurationEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SpellFocusObjectEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(SpellItemEnchantmentEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(StableSlotPricesEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(TalentEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.TalentEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(TalentID);
		CFT_IMPLEMENT_REFLECT_FIELD(TalentTab);
		CFT_IMPLEMENT_REFLECT_FIELD(Row);
		CFT_IMPLEMENT_REFLECT_FIELD(Col);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(RankID, R"(wow_dbc:"element_size:MAX_TALENT_RANK")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(DependsOn, R"()");
		CFT_IMPLEMENT_REFLECT_FIELD(DependsOnRank);
		CFT_IMPLEMENT_REFLECT_FIELD(DependsOnSpell);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(TalentTabEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_ANNOTATION_BEGIN(TaxiNodesEntry, cftc::reflect::Object, R"(wow_dbc:"fmt:dbc.fmt.TaxiNodesEntryfmt")");
		CFT_IMPLEMENT_REFLECT_FIELD(ID);
		CFT_IMPLEMENT_REFLECT_FIELD(map_id);
		CFT_IMPLEMENT_REFLECT_FIELD(x);
		CFT_IMPLEMENT_REFLECT_FIELD(y);
		CFT_IMPLEMENT_REFLECT_FIELD(z);
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(name, R"(wow_dbc:"element_size:8")");
		CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(MountCreatureID, R"(wow_dbc:"element_size:2")");
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(TaxiPathEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(TaxiPathNodeEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(WMOAreaTableEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(WorldMapAreaEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(WorldSafeLocsEntry, cftc::reflect::Object);
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	SkillRangeType SkillLineEntry::GetSkillRangeType(bool racial) const
	{
		switch (categoryId)
		{
		case SKILL_CATEGORY_LANGUAGES:
			return SKILL_RANGE_LANGUAGE;
		case SKILL_CATEGORY_WEAPON:
			if (id != SKILL_FIST_WEAPONS)
			{
				return SKILL_RANGE_LEVEL;
			}
			else
			{
				return SKILL_RANGE_MONO;
			}
		case SKILL_CATEGORY_ARMOR:
		case SKILL_CATEGORY_CLASS:
			if (id != SKILL_POISONS && id != SKILL_LOCKPICKING)
			{
				return SKILL_RANGE_MONO;
			}
			else
			{
				return SKILL_RANGE_LEVEL;
			}
		case SKILL_CATEGORY_SECONDARY:
		case SKILL_CATEGORY_PROFESSION:
			// not set skills for professions and racial abilities
			if (IsProfessionSkill(id))
			{
				return SKILL_RANGE_RANK;
			}
			else if (racial)
			{
				return SKILL_RANGE_NONE;
			}
			else
			{
				return SKILL_RANGE_MONO;
			}
		default:
		case SKILL_CATEGORY_ATTRIBUTES:                     // not found in dbc
		case SKILL_CATEGORY_GENERIC:                        // only GENERIC(DND)
			return SKILL_RANGE_NONE;
		}
	}

	bool SkillLineEntry::IsPrimaryProfessionSkill(unsigned int skill)
	{
		SkillLineEntry const* pSkill = SkillLineEntry::GetElement(skill);
		if (!pSkill)
		{
			return false;
		}

		if (pSkill->categoryId != SKILL_CATEGORY_PROFESSION)
		{
			return false;
		}

		return true;
	}

	bool SkillLineEntry::IsProfessionSkill(unsigned int skill) 
	{
		return  IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID;
	}

	void TalentEntry::MetaInstanceInit1()
	{
		for (std::size_t i = 0; i < MAX_TALENT_RANK; ++i) {
			auto id = RankID.at(i);
			if (id) {
				talent_spell_pos_map_[id] = TalentSpellPos(TalentID, (unsigned char)i);
			}
		}
	}

	TalentSpellPos const* TalentEntry::GetTalentSpellPos(unsigned int spell_id)
	{
		auto itr = talent_spell_pos_map_.find(spell_id);
		return itr != talent_spell_pos_map_.end() ? &itr->second : nullptr;
	}
	 
	unsigned int SpellEntry::GetTalentSpellCost(TalentSpellPos const* pos) const
	{
		if (pos)
		{
			return pos->rank + 1;
		}

		return 0;
	}

	unsigned int SpellEntry::GetTalentSpellCost() const
	{
		return GetTalentSpellCost(TalentEntry::GetTalentSpellPos(Id));
	}

	SpellCastResult SpellEntry::GetErrorAtShapeshiftedCast(unsigned int form) const
	{
		// talents that learn spells can have stance requirements that need ignore
			// (this requirement only for client-side stance show in talent description)
		if (GetTalentSpellCost() > 0 &&
			(Effect.at(EFFECT_INDEX_0) == SPELL_EFFECT_LEARN_SPELL || Effect.at(EFFECT_INDEX_1) == SPELL_EFFECT_LEARN_SPELL || Effect.at(EFFECT_INDEX_2) == SPELL_EFFECT_LEARN_SPELL))
		{
			return SPELL_CAST_OK;
		}

		unsigned int stanceMask = (form ? 1 << (form - 1) : 0);

		if (stanceMask & StancesNot)                 // can explicitly not be casted in this stance
		{
			return SPELL_FAILED_NOT_SHAPESHIFT;
		}

		if (stanceMask & Stances)                    // can explicitly be casted in this stance
		{
			return SPELL_CAST_OK;
		}

		bool actAsShifted = false;
		if (form > 0)
		{
			dbc::SpellShapeshiftFormEntry const* shapeInfo = dbc::SpellShapeshiftFormEntry::GetElement(form);
			if (!shapeInfo)
			{
				cftf::loger::SysLog::Instance().Error(std::format("GetErrorAtShapeshiftedCast: unknown shapeshift {}", form));
				return SPELL_CAST_OK;
			}
			actAsShifted = !(shapeInfo->flags1 & 1);            // shapeshift acts as normal form for spells
		}

		if (actAsShifted)
		{
			if (HasAttribute(SPELL_ATTR_NOT_SHAPESHIFT)) // not while shapeshifted
			{
				return SPELL_FAILED_NOT_SHAPESHIFT;
			}
			else if (Stances != 0)                   // needs other shapeshift
			{
				return SPELL_FAILED_ONLY_SHAPESHIFT;
			}
		}
		else
		{
			// needs shapeshift
			if (!HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && Stances != 0)
			{
				return SPELL_FAILED_ONLY_SHAPESHIFT;
			}
		}

		return SPELL_CAST_OK;
	}
}
